using System;
using System.Collections.Generic;
using System.Text;

namespace Developex.DatabaseWrapper.Fields
{
	/// <summary>
	/// Selects average of child items
	/// </summary>
	/// <typeparam name="ItemType">Child item type</typeparam>
	public class ItemsAverageField<ItemType> : FictitiousField<double> where ItemType : Row, new()
	{
		private readonly string foreignKeyName;
		private readonly string foreignTargetFieldName;

		private string whereString = string.Empty;

		#region Properties

		/// <summary>
		/// Insert condition
		/// </summary>
		public string WhereString
		{
			get { return whereString; }
			set { whereString = value; }
		}
		#endregion
		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		/// <param name="flags"></param>
		/// <param name="foreignKeyName"></param>
		/// <param name="foreignTargetFieldName"></param>
		public ItemsAverageField(string name, FieldFlags flags, string foreignKeyName, string foreignTargetFieldName)
			: base(name, flags)
		{
			this.foreignKeyName = foreignKeyName;
			this.foreignTargetFieldName = foreignTargetFieldName;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		/// <param name="foreignKeyName"></param>
		/// <param name="foreignTargetFieldName"></param>
		public ItemsAverageField(string name, string foreignKeyName, string foreignTargetFieldName)
			: base(name)
		{
			this.foreignKeyName = foreignKeyName;
			this.foreignTargetFieldName = foreignTargetFieldName;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public override string GetSelectExpression()
		{
			return string.Format("(CASE WHEN {0}.[Count] IS NULL THEN 0 ELSE {0}.[Count] END)", Name);
		}

		///<summary>
		///</summary>
		///<returns></returns>
		/// <remarks>overrided in ForeignField to avoid adding not used joins</remarks>
		public override bool NeedToPrepare()
		{
			return true;
		}

		/// <summary>
		/// Add joins and etc.
		/// </summary>
		/// <param name="qb">query builder</param>
		/// <remarks>don't forget to call qb.</remarks>
		public override void PrepareForSelectQuery(QueryBuilder qb)
		{
			base.PrepareForSelectQuery(qb);
			ItemType sampleItem = new ItemType();
			qb.Join.Add(string.Format(@"
left join(
select {0}, AVG(CAST({4} AS float)) as [Count] from {1}
{5}
group by {0}) {2} on {2}.{0} = {3}
", foreignKeyName, sampleItem.TableName, Name, Parent.PrimaryKeyField.GetSelectExpression(), foreignTargetFieldName, WhereString));
		}
	}
}
